﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace CommunicationModule
{
    public class TCPService
    {
        private Socket socketService;
        private Dictionary<string, Socket> currentSocket = new Dictionary<string, Socket>();
        private static readonly TCPService instance = new TCPService();
        public event Action<string> SendMessage;
        public event Action<Dictionary<string, Socket>> AddSocketList;

        public static TCPService Instance => instance;
        private TCPService() { }
        public Dictionary<string, Socket> CurrentSocket { get => currentSocket; set => currentSocket = value; }

        public void StartService(string ip, int com)
        {
            if (socketService != null)
            {
                SendInfo("服务已开启！");
                return;
            }
            socketService = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPAddress iPAddress = IPAddress.Parse(ip);
            IPEndPoint ipe = new IPEndPoint(iPAddress, com);
            socketService.Bind(ipe);
            socketService.Listen(10);
            //开启监控线程
            Task.Run(new Action(() =>
            {
                while (true)
                {
                    try
                    {
                        Socket tempSocket = socketService?.Accept();
                        string tempIP = tempSocket?.RemoteEndPoint.ToString();
                        currentSocket.Add(tempIP, tempSocket);
                        SendInfo(tempIP + "已上线！");
                        AddSocketList?.Invoke(currentSocket);
                        //开启接收线程
                        Task.Run(new Action(() => { Recv(tempSocket); }));
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }
            }));
            SendInfo("服务已开启！");
        }
        private void Recv(Socket tempSocket)
        {
            while (true)
            {
                if (tempSocket != null)
                {
                    try
                    {
                        string tempIP = tempSocket.RemoteEndPoint.ToString();
                        byte[] buffer = new byte[1024 * 1024 * 10];
                        int length = -1;
                        length = tempSocket.Receive(buffer);
                        if (length > 0)
                        {
                            string info = Encoding.Default.GetString(buffer, 0, length);
                            SendInfo($"已接收{tempIP}内容：{info}");
                        }
                        else
                        {
                            currentSocket.Remove(tempIP);
                            AddSocketList?.Invoke(currentSocket);
                            SendInfo(tempIP + "已下线！");
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }
            }
        }
        private void SendInfo(string info) => SendMessage?.Invoke(info);
        public void Close()
        {
            if (socketService != null)
            {
                socketService.Close();
                foreach (Socket item in currentSocket.Values)
                {
                    item.Close();
                }
                currentSocket.Clear();
                socketService = null;
                AddSocketList?.Invoke(currentSocket);
                SendInfo("服务已关闭！");
            }
        }
        public void Send(string info, string temIP)
        {
            foreach (KeyValuePair<string, Socket> item in currentSocket)
            {
                if (item.Key == temIP)
                {
                    byte[] buffer = new byte[1024 * 1024 * 10];
                    buffer = Encoding.Default.GetBytes(info.Trim());
                    item.Value.Send(buffer);
                    SendInfo($"已向{item.Key}发送：{info}");
                }
            }
        }
    }
}
